import externalContent.ApplicationStructureDataManager;
import externalContent.NavigationGenerator;

import gugga.application.ApplicationController;
import gugga.application.NavigationManager;
import gugga.common.EventDescriptor;
import gugga.common.ITask;
import gugga.components.SectionLoader;
import gugga.navigation.MenuNavigation;
import gugga.sequence.ExecuteAsyncMethodTask;
import gugga.sequence.ExecuteMethodTask;
import gugga.sequence.TaskSequence;

/** 
 * @author bony
 * In this application all the data is external. The information for all the sections is in the "application.xml" file.
 * Each section has individual swf fail. The path to the section's swfs is in the application swf too.
 */
class externalContent.Application extends ApplicationController
 {
 	// List all the application fields here.
 	 
 	private var mMainNavigation: MenuNavigation;
 	
 	// In the "mSectionsContainer" movie clip the sections swfs are loaded with the "SectionLoader".
 	private var mSectionsContainer: MovieClip;
 	
 	private var mDataManager: ApplicationStructureDataManager;
 	private var mNavigationGenerator: NavigationGenerator;
 	
	function Application() 
	{
		super();
		
		// The function getComponent creates a mapping between the instances on the scene and
		// the member variables of the Application class.
		mMainNavigation = getComponent("MainNavigation");
		mSectionsContainer = getComponent("SectionsContainer");
		
		// Create NavigationGenerator.
		// The NavigationGenerator lays out the buttons of the "mMainNavigation". 
		mNavigationGenerator = new NavigationGenerator();
		
		// Create "ApplicationStructureDataManager", which transforms the data from the xml file (application.xml)
		// to format necessary for the LayoutGenerator. 
		mDataManager = new ApplicationStructureDataManager();		
	}
	
	// All Objects instantiated inside the Application inherit UIComponentEx except macromedia components.
	// This function is required because we have to make sure that 
	// all objects inside the Application are associated with their respective classes and are avaialable and ready to work.
	// All sections are phisically nested inside the main Application and their initialization is not immediate.
	// Before execution of that function you cannot call any event related methods or mixin related methods of the objects.
	
	private function initUI() : Void
	{
		super.initUI();		
		
		// Initialization sequence
		var applicationConfigureSequence: TaskSequence = new TaskSequence();
		applicationConfigureSequence = prepareInitializingSequence();
		
		this.registerInitializingTask(applicationConfigureSequence);
		
		NavigationManager.Instance.registerNavigation(mMainNavigation, "MainNavigation");
		
		// Trigger initializing sequence.
		initialize();			
			
		// Activating sequence		
		// Using default activating sequence.
		
		// Open sequence		
		// Using default open sequence.
		
		// Close sequence		
		// Using default close sequence.	
	}
	
	private function prepareInitializingSequence() : TaskSequence
	{
		// The load data is asynchronous method. Wait the event "dataLoaded" to complete.
		// This task loads the application data. 	
		var loadDataTask: ITask = ExecuteAsyncMethodTask.create
									(
										new EventDescriptor(mDataManager, "dataLoaded"),
										mDataManager, 
										mDataManager.loadData
									);
									 		
		// Navigation generation is asynchronous method. Wait the event "generationFinished" to complete.	
		// The NavigationGenerator lays out and registers the menu items.	
		var navigationGeneratorTask: ITask = ExecuteAsyncMethodTask.create
											(
												new EventDescriptor(mNavigationGenerator, "generationFinished"),
												this, this.generateNavigation										
											);
		
		// Register the sections.
		var registerSectionsTask: ITask = ExecuteMethodTask.create(this, this.registerSections);		var startNavigationsTask: ITask = ExecuteMethodTask.create(NavigationManager.Instance, NavigationManager.Instance.startNavigations);
		
		// Initialization sequence
		var applicationConfigureSequence: TaskSequence = new TaskSequence();
		applicationConfigureSequence.addTask(loadDataTask);
		applicationConfigureSequence.addTask(navigationGeneratorTask);	
		applicationConfigureSequence.addTask(registerSectionsTask);			applicationConfigureSequence.addTask(startNavigationsTask);	
		
		// We have to include the default sections controller Initializing Sequence
		// in order to keep the class functional. Add this task in the end, because the "mSectionsControllerInitializingSequence"
		// must be execute after the registration of the menu and sections. 
		applicationConfigureSequence.addTask(mSectionsControllerInitializingSequence);
		
		return applicationConfigureSequence;
	}
		
	private function generateNavigation(): Void
	{
		var navigationData: Object = mDataManager.getNavigationData();
		
		// "mNavigationGenerator" generates the navigation buttons in the container "mMainNavigation"
		mNavigationGenerator.generate(navigationData, mMainNavigation);		
	}

	private function registerSections() : Void 
	{
		var sectionLoader: SectionLoader;
		
		var sectionSWF: String;
		var sectionID: String;			
		
		// Create array, which contain all sections with their data. 
		var sectionData : Array = mDataManager.getSectionData();
		
		// For all sections create "SectionLoader" and attach it to the mSectionsContainer.
		// Get the path to the swf and the identifier (ID) for every section.								
		for (var i:Number = 0; i < sectionData.length; i++) 
		{
			sectionSWF = sectionData[i].attributes["swf"];
			sectionID = sectionData[i].attributes["ID"];
							
			sectionLoader = SectionLoader
				(
					mSectionsContainer.attachMovie
					(
						"SectionLoader",
						"SectionLoader" + sectionID,
						mSectionsContainer.getNextHighestDepth()
					 )
				 );
				 
			// Register the section.
			// All sections are lazy load, because they are loaded from external swf.
			// The section ID and the menu item ID are equal.
			registerLazyLoadSection(sectionLoader, sectionSWF, sectionID, false);
		}
	}	
}